package com.gitee.wsl.transform.validator

import arrow.core.Either
import arrow.core.leftNel
import arrow.core.right
import com.gitee.wsl.test.shouldBe
import com.gitee.wsl.transform.validator.func.map
import com.gitee.wsl.transform.validator.func.mapIfNotNull
import com.gitee.wsl.transform.validator.func.notNull
import com.gitee.wsl.transform.validator.func.nullable
import com.gitee.wsl.transform.validator.strings.length
import com.gitee.wsl.transform.validator.strings.match
import com.gitee.wsl.transform.validator.strings.maxlen
import com.gitee.wsl.transform.validator.strings.minlen
import com.gitee.wsl.transform.validator.strings.notNullOrBlank
import com.gitee.wsl.transform.validator.strings.strip
import kotlin.test.Test


class StringTest  {
      @Test
      fun testnotnull() {
         val p = ValidatorWithTransform<String?>().notNull { "cannot be null" }.map { Foo(it) }
         p.validate(null) shouldBe "cannot be null".leftNel()
      }

   @Test
   fun testnotnullorblank() {
         val p = ValidatorWithTransform<String>().nullable().notNullOrBlank { "cannot be null or blank" }.map { Foo(it) }
         p.validate("") shouldBe "cannot be null or blank".leftNel()
         p.validate("     ") shouldBe "cannot be null or blank".leftNel()
         p.validate(null) shouldBe "cannot be null or blank".leftNel()
      }

   @Test
   fun testminlength() {
         val p = ValidatorWithTransform<String>().minlen(4) { "too short" }.map { Foo(it) }
         p.validate("abc") shouldBe "too short".leftNel()
         p.validate("abcd") shouldBe Foo("abcd").right()
      }

   @Test
   fun testminlengthornull() {
         val p = ValidatorWithTransform<String?>().minlen(4) { "too short" }.mapIfNotNull { Foo(it) }
         p.validate("abc") shouldBe "too short".leftNel()
         p.validate("abcd") shouldBe Foo("abcd").right()
         p.validate(null) shouldBe Either.Right(null)
      }

   @Test
   fun testmaxlength() {
         val p = ValidatorWithTransform<String>().maxlen(4) { "too long" }.notNull { "not null" }.map { Foo(it) }
         p.validate("abcde") shouldBe "too long".leftNel()
         p.validate("abcd") shouldBe Foo("abcd").right()
         p.validate("abc") shouldBe Foo("abc").right()
      }

   @Test
   fun testmaxlengthonnullablestring() {
         val p = ValidatorWithTransform<String?>().maxlen(4) { "too long" }.mapIfNotNull { Foo(it) }
         p.validate("abcde") shouldBe "too long".leftNel()
         p.validate("abcd") shouldBe Foo("abcd").right()
         p.validate("abc") shouldBe Foo("abc").right()
         p.validate(null) shouldBe Either.Right(null)
      }

   @Test
   fun testlength() {
         val p = ValidatorWithTransform<String>().length(4) { "must be 4 chars" }.map { Foo(it) }
         p.validate("abcde") shouldBe "must be 4 chars".leftNel()
         p.validate("abcd") shouldBe Foo("abcd").right()
         p.validate("abc") shouldBe "must be 4 chars".leftNel()
      }


   
   @Test
   fun teststrip() {
         val p = ValidatorWithTransform<String>().strip(charArrayOf('a', 'b'))
         p.validate("aaccbb") shouldBe "cc".right()
         p.validate("aa") shouldBe "".right()
         p.validate("ddd") shouldBe "ddd".right()
      }

   @Test
   fun testmatch() {
         val p = ValidatorWithTransform<String>().match("aa.".toRegex()) { "$it is whack!" }
         p.validate("aab") shouldBe "aab".right()
         p.validate("aac") shouldBe "aac".right()
         p.validate("aa") shouldBe "aa is whack!".leftNel()
         p.validate("baa") shouldBe "baa is whack!".leftNel()
      }
   
}
